<html>

<head>
    <title>全景</title>
    <meta name="description" content="全景示例罢了">
    <style>
        html,
        body {
            margin: 0;
            height: 100%;
            width: 100%;
        }

        div[load] {
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            height: 48px;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            background-color: #aaaa;
            backdrop-filter: blur(3px);
        }

        div[load]>input {
            font-size: 1rem;
        }

        @media all and (max-width: 981px) {
            div[load] {
                height: 128px;
            }

            div[load]>input {
                font-size: 3rem;
            }
        }
    </style>
</head>

<body>
    <div id="app">
        <div id="container"></div>
    </div>
</body>
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js"></script> -->
<script src="./js/vue.js"></script>
<script type="module">
    import * as THREE from "./three/build/three.module.js"
    import { OrbitControls } from "./three/examples/jsm/controls/OrbitControls.js"
    import States from "./three/examples/jsm/libs/stats.module.js"


    window.onload = () => {
        const inst = new Vue({
            el: "#app",
            data() {
                return {
                    // 调试控制面板
                    cp: {
                        camera: {
                            x: 0,
                            y: 0,
                            z: 100
                        }
                    },
                    // 渲染驱动对象
                    scene: null,
                    camera: null,
                    renderer: null,
                    sphere: null,
                    ambLight: null,
                    // 性能检测对象
                    states: null,
                }
            },
            computed: {
                sceneBg() {
                    let bgUrl = "./images/360-2.jpg"
                    const refer = location.href.split("?")
                    if (refer.length > 1) {
                        // 没什么东西，就是一个url参数拆分
                        const pg = refer[1].split("&").map(p => p.split("=")).reduce((pps, [k, v]) => { pps[k] = v; return pps }, {}) // params group
                        if (pg.url) bgUrl = pg.url
                    }
                    return bgUrl
                }
            },
            methods: {
                // 创建场景、相机、渲染器
                init() {
                    this.scene = new THREE.Scene()
                    this.scene.background = 0xf0f0f0
                    this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000)
                    // 内部相机就设置到场景中心
                    const { x, y, z } = this.cp.camera
                    this.camera.position.set(x, y, z)
                    // this.camera.position.set(0, 300, 0)
                    // this.camera.lookAt(0, 0, 0)
                    // 条件许可的情况下，打开抗锯齿
                    this.renderer = new THREE.WebGLRenderer({ antilise: true })
                    this.renderer.setPixelRatio = window.devicePixelRatio
                    this.renderer.setSize(window.innerWidth, window.innerHeight)
                    container.appendChild(this.renderer.domElement)
                    // 创建性能检测对象
                    // this.states = new States()
                    // container.appendChild(this.states.dom) 
                    console.log("创建场景、渲染器完成")
                },
                // 创建全景球面
                initSphere() {
                    if (this.sphere) {
                        this.sphere.material.map = new THREE.TextureLoader().load(this.sceneBg)
                        return
                    }
                    const sphereGeo = new THREE.SphereGeometry(2000, 2000, 30) // 半径，网格划分
                    sphereGeo.scale(1, 1, -1) // 翻转法向平面 
                    const sphereMaterial = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(this.sceneBg) })
                    this.sphere = new THREE.Mesh(sphereGeo, sphereMaterial)
                    this.scene.add(this.sphere)
                    console.log("创建全景贴图球面完成")
                },
                initControls() {
                    const control = new OrbitControls(this.camera, this.renderer.domElement)
                    control.rotateSpeed = -1
                    this.control = control
                },
                // 顶部加个环境光
                initLight() {
                    // 环境光
                    this.ambLight = new THREE.AmbientLight(0xfefeff, 2)
                    this.scene.add(this.ambLight)
                },
                animate() {
                    requestAnimationFrame(this.animate)
                    this.camera.rotation.y -= 0.0002
                    this.renderer.render(this.scene, this.camera)
                    this.states && this.states.update()
                },
                setSphere(e) {
                    if (e.target.files.length) {
                        const file = e.target.files[0]
                        const url = window.URL.createObjectURL(file)
                        this.sphere.material.map = new THREE.TextureLoader().load(url)
                    }
                }
            },
            created() {
                this.$nextTick(() => {
                    this.init()
                    this.initControls()
                    this.initSphere()
                    this.animate()
                    window.addEventListener("resize", e => {
                        this.camera.aspect = window.innerWidth / window.innerHeight
                        this.camera.updateProjectionMatrix()
                        this.renderer.setSize(window.innerWidth, window.innerHeight)
                    })
                })
            },
        })
    }
</script>

</html>